package org.myhibernate.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class SingleConnection 
{
	private Connection connection=null;
	private String type=null;
	
	public SingleConnection() 
	{
		Runtime.getRuntime().addShutdownHook(new Thread()
		{
			@Override
			public void run() 
			{
				close();
			}
		});
	}
	
	public SingleConnection(String type) {
		this.type = type;
	}

	public Connection getConnectionInstance() throws Exception
	{
		if ("true".equals(StaticConfigs.getAttribute("trance.enable")))
		{
			CommonLogs.add(showAllStackTrance());
		}
		if (type==null) {
			type=StaticConfigs.getAttribute("connect.type");
		}
		if ("jndi".equals(type)) {
			return getConnectionByJndi(StaticConfigs.getAttribute("db.jndi.name"));
		}else if ("c3p0".equals(type)) 
		{
			return DBPool.getConnection();
		}
		//other
		type=StaticConfigs.getAttribute("db.type");
		String driver=StaticConfigs.getAttribute(type+".jdbc.driver");
		String url=StaticConfigs.getAttribute(type+ ".jdbc.url");
		String username=StaticConfigs.getAttribute(type+".jdbc.username");
		String password=StaticConfigs.getAttribute(type+".jdbc.password");
		System.out.println("get connection with:"+type+","+driver+","+url+","+username+","+password);
		 try
	  	    {
	  	      Class.forName(driver);
	  	      this.connection = DriverManager.getConnection(url, username, password);
	  	      System.out.println("SingleConnection getConnectionInstance");
	  	      return this.connection;
	  	    }
	  	    catch (Exception e) 
	  	    {
	  	    	System.out.println("Exception for connection to databaase:"+SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
	  	    	System.out.println("type="+type);
	  	    	System.out.println("driver="+driver);
	  	    	System.out.println("url="+url);
	  	    	System.out.println("username="+username);
	  	    	System.out.println("password="+password);
	  	    	CommonLogs.add("Exception for connection to databaase:"+SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
	  	    	CommonLogs.add("type="+type);
	  	    	CommonLogs.add("driver="+driver);
	  	    	CommonLogs.add("url="+url);
	  	    	CommonLogs.add("username="+username);
	  	    	CommonLogs.add("password="+password);
	  	    	e.printStackTrace();
	  	    throw new RuntimeException("Error to create connection");
	  	    }
	}
	public  Connection getConnectionByJndi(String jndiName) throws Exception
	  {
		//System.out.println("get connection to database:"+SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
		//System.out.println(" jndiName=========="+jndiName);
		CommonLogs.add("get connection to database:"+SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
		CommonLogs.add("jndiName=========="+jndiName);
		  Context initContext=null;
			DataSource ds =null;
			try {
				initContext = new InitialContext();
				ds = (DataSource) initContext.lookup(jndiName);
				return ds.getConnection();
			} catch (Exception e) {
				System.out.println("Exception for connection to database:"+SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
				System.out.println("Exception for jndiName=========="+jndiName);
				CommonLogs.add("Exception for connection to database:"+SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
				CommonLogs.add("Exception for jndiName=========="+jndiName);
				e.printStackTrace();
				throw new RuntimeException("Error to create connection with jndi :"+jndiName);
			}
		  
	  }
	public String showAllStackTrance()
	{
		StringBuffer buffer=new StringBuffer();
		buffer.append("*************************************************************showAllStackTrance start*************************************************************\n");
		buffer.append(SingleConnection.class.getProtectionDomain().getCodeSource().getLocation().getFile());
		 for (final Map.Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet()) 
		 {
	            final Thread thread = entry.getKey();
	            final StackTraceElement[] stack = entry.getValue();
	            for (final StackTraceElement frame : stack) 
	            {
	            	buffer.append(thread.getName() + " = " + frame+"\n");
	            }
	        }
		 buffer.append("*************************************************************showAllStackTrance end*************************************************************\n");
		 return buffer.toString();
	}
	public void close()
	{
		try {
			if (connection!=null) {
				connection.close();
			}
		} catch (Exception e) {
		}
	}
}
